package com.ych.init.filter;

import com.ych.utils.AuthInitAccessUtil;
import com.ych.utils.TLMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * Author: Usopp.tsui
 * Date: 2020/12/5
 * Time: 15:04
 * Description:
 */
@Configuration
public class AccessFilter implements Filter {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        try {
            logger.info("创建当前线程请求{}", " url: " + req.getRequestURI());
            //防刷新,同一个IP地址2秒内不允许超过1千次请求
            AuthInitAccessUtil.requestLimit(req);

            //可直接请求通过
            if (AuthInitAccessUtil.adopt(req)) {
                chain.doFilter(request, response);
                return;
            }

            //调试模式校验
            if (AuthInitAccessUtil.swaggerDebug(req)) {
                chain.doFilter(request, response);
                return;
            }

            //不鉴权请求通过
            if (unAuthCheck(req)) {
                chain.doFilter(request, response);
                return;
            }
            AuthInitAccessUtil.authUserAndToken(req);//验证用户和token
            //登录用户标识
            TLMap.setAuthUser(true);
            chain.doFilter(request, response);//继续下一个过滤器
        } catch (Exception e) {
            e.printStackTrace();
            AuthInitAccessUtil.responseException(response, e);
        } finally {
            logger.info("准备销毁线程请求{}", " url: " + req.getRequestURI() + " 当前线程状态:  " + TLMap.queryTLMap());
            try {
                //如果含有认证登录用户标识,代表调用过需要认证的接口,则进行共享存储处理
                if (TLMap.getAuthUser()) {
                    shiroRedisUpdate(request);
                }
                if (0 == req.getRequestURI().indexOf("/api/unAuth/login")
                        || 0 == req.getRequestURI().indexOf("/cms/unAuth/login")) {
                    shiroRedisUpdate(request);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
//            try {
//                TLMap.destroy();//销毁对象
//                logger.info("销毁当前线程请求{}", " url: " + req.getRequestURI() + " 当前线程状态:  " + TLMap.queryTLMap());
//            } catch (Exception e) {
//
//            }
        }
    }

    /**
     * 共享缓存
     *
     * @param request
     */
    private void shiroRedisUpdate(ServletRequest request) {
//        String sessionId = RedisKeyConfig.sessionToken(TLMap.getUserId());
//        BeanFactory factory = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
//        RedisUtil redisTemplate = (RedisUtil) factory.getBean("redisUtil");
//        TokenSessionEntity tokenSessionEntity =(TokenSessionEntity)TLMap.getTlMap(sessionId);
//        String user_id = TLMap.getUserId();
//        if (StringUtils.isBlank(user_id) || user_id.toUpperCase().equals("NULL")) {
//            return;
//        }
//        if (null != tokenSessionEntity) {
//            //刷入redis
//            redisTemplate.redisTemplate().opsForValue().set(sessionId, tokenSessionEntity);
//            redisTemplate.redisTemplate().expire(sessionId, RedisKeyConfig.expireTime, TimeUnit.SECONDS);
//        }
    }

    /**
     * 不鉴权请求通过
     *
     * @param req
     * @return
     */
    private boolean unAuthCheck(HttpServletRequest req) {
        if (0 == req.getRequestURI().indexOf("/cms/unAuth/")
                || 0 == req.getRequestURI().indexOf("/api/unAuth/")
                || 0 == req.getRequestURI().indexOf("/file")) {  //此处必须等于0,等于0为全匹配校验
            AuthInitAccessUtil.appendUserAndToken(req);//追加当前请求
            return true;
        } else {
            return false;
        }
    }

    @Override
    public void destroy() {
    }
}
